package com.sx.pipeline.ui.linepipe.file

import android.annotation.SuppressLint
import android.app.Application
import android.graphics.BitmapFactory
import android.text.TextUtils
import android.widget.EditText
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.ThreadUtils
import com.blankj.utilcode.util.ToastUtils
import com.bumptech.glide.Glide
import com.dinnovate.dxf.DXF
import com.dinnovate.dxf.collector.DxfCollector
import com.dinnovate.dxf.entity.GeometricPolyLine
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.core.BasePopupView
import com.sx.mvvmlibs.binding.edittext.viewAdapter
import com.sx.mvvmlibs.event.SingleLiveEvent
import com.sx.mvvmlibs.utils.Logs
import com.sx.pipeline.app.model.CYBaseViewModel
import com.sx.pipeline.repos.local.db.table.FileNodesBeanDO
import com.sx.pipeline.repos.local.db.table.PipeFileBeanDO
import com.sx.pipeline.utils.CompressHelper
import com.sx.pipeline.utils.GPSUtil
import com.sx.pipeline.utils.kml.FileParseBean
import com.sx.pipeline.utils.kml.KmlHelper
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.functions.Consumer
import io.reactivex.rxjava3.schedulers.Schedulers
import java.io.File
import java.io.FileInputStream

/**
 * @Author: YY
 * @Date: 2022/8/10
 * @Desc: TODO
 */
class LinePipeFilesVM(app: Application) : CYBaseViewModel(app) {

    val fileTypeEvent: SingleLiveEvent<Boolean> = SingleLiveEvent()

    /**
     * 解析 KML文件
     */
    val fileBeanListEvent: SingleLiveEvent<MutableList<FileParseBean>> = SingleLiveEvent()

    fun kmlAnalysis(kmlFile: File) {

        ThreadUtils.executeBySingle(object : ThreadUtils.Task<MutableList<FileParseBean>>() {

            override fun doInBackground(): MutableList<FileParseBean> {
                showLoadingDialog("正在解析...")
                return KmlHelper().parseKml(kmlFile)
            }

            override fun onSuccess(result: MutableList<FileParseBean>?) {
                dismissLoadingDialog()
                if (!result.isNullOrEmpty()) {
                    Logs.d("onSuccess LinePipeFilesVM ${result.size}")
                    if (result.size == 0) {
                        ToastUtils.showShort("KML文件不符合规范")
                        return
                    }
                    val lineList = mutableListOf<FileParseBean>()
                    result.forEach {
                        if (it.type == 2) {
                            Logs.d("onSuccess LinePipeFilesVM${it.type}")
                            lineList.add(it)
                        }
                    }
                    if (lineList.isEmpty()) {
                        ToastUtils.showShort("KML文件不符合规范")
                        return
                    }
                    fileBeanListEvent.postValue(lineList)
                    fileTypeEvent.postValue(true)
                }
            }

            override fun onCancel() {
                dismissLoadingDialog()
            }

            override fun onFail(t: Throwable?) {
                dismissLoadingDialog()
            }
        })
    }

    /**
     * dxf文件解析数据
     */

    fun dxfAnalysis(dxfFile: File) {
        ThreadUtils.executeBySingle(object : ThreadUtils.Task<DxfCollector>() {
            override fun doInBackground(): DxfCollector {
                showLoadingDialog("正在解析...")
                return DXF.build(FileInputStream(dxfFile), "UTF-8")
            }

            override fun onSuccess(result: DxfCollector?) {
                dismissLoadingDialog()
                if (result != null) {
                    Logs.d("onSuccess LinePipeFilesVM${result.map}")
                    Logs.d("onSuccess LinePipeFilesVM${result.map.size}")
                    if (result.map.size > 1) {
                        ToastUtils.showShort("DXF文件不符合规范")
                        return
                    }
                    try {
                        val geometricPolyLine: List<GeometricPolyLine>? =
                            result.map["LWPOLYLINE"] as List<GeometricPolyLine>
                        if (!geometricPolyLine.isNullOrEmpty()) {
                            var degrees1 = 114
                            var isPlus = false
                            if (geometricPolyLine[0].vertexList[0].x.toInt()
                                    .toString().length > 6
                            ) {
                                isPlus = true
                                // 判断x轴 是否大于6位
                                val firstTwo =
                                    geometricPolyLine[0].vertexList[0].x.toInt().toString()
                                        .substring(0, 2).toInt()
                                Logs.d("onSuccess $firstTwo")
                                degrees1 = if (firstTwo >= 24) {
                                    firstTwo * 3
                                } else {
                                    firstTwo * 6 - 3
                                }
                            }
                            showInputDialog(degrees1, geometricPolyLine, isPlus)
                        }
                    } catch (e: Exception) {
                        ToastUtils.showShort("解析出现问题")
                    }

                }
            }

            override fun onCancel() {
                Logs.d("onCancel")
                dismissLoadingDialog()
            }

            override fun onFail(t: Throwable?) {
                Logs.d("onFail")
                dismissLoadingDialog()
            }
        })
    }

    @SuppressLint("StaticFieldLeak")
    private lateinit var mPopup: BasePopupView

    /**
     * 输入名称
     */
    private fun showInputDialog(
        degrees: Int,
        geometricPolyLine: List<GeometricPolyLine>,
        isPlus: Boolean
    ) {
        mPopup = XPopup.Builder(ActivityUtils.getTopActivity())
            .autoDismiss(false)
            .asInputConfirm(
                "中央子午线设置",
                "", degrees.toString(), "请输入中央子午线"
            ) {
                if (!TextUtils.isEmpty(it)) {
                    if (it.toInt() in 73..135) {
                        transformDxfData(it.toInt(), geometricPolyLine, isPlus)
                    } else {
                        ToastUtils.showShort("中央子午线超过国家范围")
                    }
                    mPopup.dismiss()
                } else {
                    ToastUtils.showShort("请输入中央子午线")
                }
            }.also {
                val editText = it.findViewById<EditText>(com.lxj.xpopup.R.id.et_input)
                viewAdapter.filterEditText(editText, true)
            }.show()
    }

    private fun transformDxfData(
        degrees: Int = 114,
        geometricPolyLine: List<GeometricPolyLine>,
        isPlus: Boolean
    ) {
        val fileParseBeanList: MutableList<FileParseBean> = mutableListOf()
        val fileParse = FileParseBean()
        fileParse.type = 2

        val centerList: MutableList<FileParseBean.NodesBean> = mutableListOf()
        geometricPolyLine.forEach { data ->
            data.vertexList.forEach { vertexList ->
                if (isPlus) {
                    // 如果带加号 去掉前两位
                    vertexList.x = vertexList.x.toString().substring(2).toBigDecimal()
                    Logs.d("transformDxfData ${vertexList.x.toDouble()}")
                }
                val nodesBean = FileParseBean.NodesBean(
                    GPSUtil.CGS2000ToWGS84(
                        vertexList.y.toDouble(),
                        vertexList.x.toDouble(),
                        degrees.toDouble()
                    )[1],
                    GPSUtil.CGS2000ToWGS84(
                        vertexList.y.toDouble(),
                        vertexList.x.toDouble(),
                        degrees.toDouble()
                    )[0]
                )
                centerList.add(nodesBean)
            }
            fileParse.nodesBeans = centerList
            fileParseBeanList.add(fileParse)
            fileBeanListEvent.postValue(fileParseBeanList)
            fileTypeEvent.postValue(false)
        }
    }

    /**
     * 保存数据
     */
    fun saveFileBean(fileName: String, type: Int) {
        val fileNodesBeanList: MutableList<FileNodesBeanDO> = mutableListOf()

        val fileParseBeanList: MutableList<FileParseBean> = fileBeanListEvent.value!!
        fileParseBeanList.forEach { fileParseBean ->
            fileParseBean.nodesBeans.forEach {
                val fileNodesBean = FileNodesBeanDO(
                    fileParseBean.type,
                    it.longitude.toDouble(), it.latitude.toDouble()
                )
                fileNodesBeanList.add(fileNodesBean)
            }
        }

        // 保存用户数据
        val fileBeanDO = PipeFileBeanDO(
            userId = mModel.getToken()!!, fileName = fileName,
            fileType = type, fileNodesBeanDO = fileNodesBeanList
        )

        addSubscribe(
            mModel.saveFileBean(fileBeanDO)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(Consumer {
                    ToastUtils.showShort("导入成功")
                    finish()
                })
        )
    }


}